package com.atguigu.tingshu.album.service;

import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: atguigu
 * @create: 2024-05-22 08:45
 */
@Service
public class BloomFilterService {


    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    /**
     * 抽取布隆过滤器扩容方法
     *
     * @return
     */
    public RBloomFilter resize() {
        //1.判断是否满足扩容条件 布隆过滤器元素数量>期望数据规模进行扩容
        //1.1 获取现有布隆过滤对象
        RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        //1.2 获取现有布隆过滤器各项信息（数量、误判率、数据规模）
        long count = oldBloomFilter.count();
        long expectedInsertions = oldBloomFilter.getExpectedInsertions();
        //TODO 实际运行改为现有数据规模
        if (count >= 1500) {
            //2.新建布隆过滤器，初始化期望数据规模是原来的两倍
            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
            newBloomFilter.tryInit(expectedInsertions * 2, oldBloomFilter.getFalseProbability());

            //3.将审核通过专辑ID保存新布隆过滤器
            //3.1 查询现有审核通过专辑ID
            LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS);
            queryWrapper.select(AlbumInfo::getId);
            List<AlbumInfo> list = albumInfoMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                //3.2 将专辑ID新增到新布隆过滤器
                List<Long> albumIdList = list.stream().map(AlbumInfo::getId).collect(Collectors.toList());
                for (Long albumId : albumIdList) {
                    newBloomFilter.add(albumId);
                }
            }
            //4.删除旧的
            oldBloomFilter.delete();

            //5.对新布隆过滤器改名
            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
            return newBloomFilter;
        }
        return null;
    }
}
